﻿#include "TcpServer.h"
#include "TcpConnectHandler.h"

TcpServer::TcpServer(int port)
{
	this->port = port;
	acceptThreadHandle = NULL;
}


TcpServer::~TcpServer()
{

}

DWORD WINAPI startAccept(LPVOID p)
{

	//FaceSdkToolPool::GetInstance()->init();

	TcpServer * pTcpServer = (TcpServer *)p;

	pTcpServer->state = RunableStateStarted;

    LOG_INFO("tcp server accept thread started, wait for next connection,listensocket:%d", pTcpServer->slisten);


	SOCKET sClient;
	sockaddr_in remoteAddr;
	int nAddrlen = sizeof(remoteAddr);

	while (pTcpServer->state == RunableStateStarted)
	{
		
		sClient = accept(pTcpServer->slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);

		//设置socket读超时,60秒
		int nNetTimeout = 60000;
		if (SOCKET_ERROR == setsockopt(sClient, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(int)))
		{
			LOG_INFO("Set Ser_RecTIMEO error !");
		}

		if (pTcpServer->state != RunableStateStarted)
		{
			break;
		}
		else if (sClient == INVALID_SOCKET)
		{
            LOG_ERROR("rcv one in valid socket");
			continue;
		}
		else
		{
			TcpConnectHandler *handler = new TcpConnectHandler(sClient);
            struct sockaddr_in addr;
            int addrlen = sizeof(addr);
            if(!getpeername(sClient, (struct sockaddr *)&addr, &addrlen))
            {
                handler->remoteIP = inet_ntoa(addr.sin_addr);
                handler->remotePort = ntohs(addr.sin_port);
            }
			handler->run();

			if (TcpConnectHandler::connnectionCount > 100)
			{
                LOG_WARN("TCP connection count:%d > 100!", TcpConnectHandler::connnectionCount);
			}
            LOG_INFO("receive one new TCP connection, connection count:%d", TcpConnectHandler::connnectionCount);
			//handler->start();
			//SafeDeleteObj(handler);
		}
	}

    LOG_INFO("tcp server accept thread stoped");
	closesocket(pTcpServer->slisten);
	WSACleanup();
	return 0;
}


int TcpServer::start()
{

	TcpConnectHandler::initSocket();

	slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (slisten == INVALID_SOCKET)
	{
        LOG_ERROR("try to create server socket failed");
		return f_fail;
	}
	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	sin.sin_addr.S_un.S_addr = INADDR_ANY;


	if (::bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
        LOG_ERROR("try to bind socket to any ip with port:%d failed", port);
		closesocket(slisten);
		return f_fail;
	}
	else
	{
        LOG_INFO("try to start listen tcp server with port:%d success", port)
	}

	if (listen(slisten, INT_MAX) == SOCKET_ERROR)
	{
        LOG_ERROR("listen socket failed with error code:%ld\n", WSAGetLastError());
		closesocket(slisten);
		WSACleanup();
		return f_fail;
	}

	startAccept(this);
	//acceptThreadHandle = CreateThread(NULL, 0, startAccept, this, 0, NULL);

	//Sleep(500);

	return f_success;
}

void TcpServer::stop()
{
	if (acceptThreadHandle != NULL)
	{
		state = RunableStateStoping;

		TcpConnectHandler* connect = TcpConnectHandler::connect("127.0.0.1", port);
		SafeDeleteObj(connect);

		WaitForSingleObject(acceptThreadHandle, INFINITE);
		CloseHandle(acceptThreadHandle);
	}
}

